/*  JEVEMon, A Java-based EVEMon clone.
    Copyright (C) 2011, Raul Ruiz

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/*
 * JEVEMeApp.java
 */

package jeveme;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.EventObject;
import javax.swing.JFrame;
import jeveme.datacontainers.EVEMasterSkillSheet;
import org.jdesktop.application.Application;
import org.jdesktop.application.SingleFrameApplication;
import jeveme.datacontainers.MasterDataContainer;
import jeveme.helpers.OperatingSystem;


/**
 * The main class of the application.
 */
public class JEVEMeApp extends SingleFrameApplication {

    /**
     * At startup create and show the main frame of the application.
     */
    @Override protected void startup() {
        
        //Add Application Exit Listeners
        this.addExitListener(new ExitListener() {

            @Override
            public boolean canExit(EventObject event) {
                System.out.println("Called can exit");
                return true;
            }

            @Override
            public void willExit(EventObject event) {
                System.out.println("Called Will Exit. Writing MDC");
               saveMasterDataContainer();
               System.out.println("Wrote MDC");
            }
        });
        
        //Check directory structure
        checkDirectories();
        
        //Load the Master Data Container
        loadMasterDataContainer();
        
        //Show the initial view.
        jview = new JEVEMeView(this);
        jview.getFrame().setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        show(jview);
    }

    /**
     * This method is to initialize the specified window by injecting resources.
     * Windows shown in our application come fully initialized from the GUI
     * builder, so this additional configuration is not needed.
     */
    @Override protected void configureWindow(java.awt.Window root) {


    }

    /**
     * A convenient static getter for the application instance.
     * @return the instance of JEVEMeApp
     */
    public static JEVEMeApp getApplication() {
        return Application.getInstance(JEVEMeApp.class);
    }

    /**
     * Main method launching the application.
     */
    public static void main(String[] args) {
        launch(JEVEMeApp.class, args);
    }
    
    /**
     * Checks for the existence of the directory structure.
     * Creates it if not in existence.
     */
    protected final void checkDirectories() {
        //First, check that the JEVEMe directory exists. Create if not.
        String dirPath = OperatingSystem.getDirPath();
        File dir = new File(dirPath);
        if(!dir.exists()) {
            dir.mkdir();
        }
        
        //Second, Image Path
        dirPath = OperatingSystem.getImagePath();        
        //See if directory exists. if not, create it.
        dir = new File(dirPath);
        if(!dir.exists()) {
            dir.mkdir();
        }
        
        return;
    }
    
    /**
     * 
     * @return 
     */
    private void loadMasterDataContainer() {
        
        String filePath = System.getProperty("user.home");
        //Determine the operating system.
        if(OperatingSystem.isWindows()) {
            filePath += "\\.JEVEMe\\" + MDC_FILENAME;
        }
        else if(OperatingSystem.isMac()) {
            filePath += "/Library/Application Support/JEVEMe/" + MDC_FILENAME;
        }
        else if(OperatingSystem.isUnix()) {
            filePath += "/.jeveme/" + MDC_FILENAME;
        }
        else {
            filePath += "/.jeveme/" + MDC_FILENAME;
        }
       
        File f = new File(filePath);
        if(f.exists()) { //Load the serialized MainDataContainer
            try{
                FileInputStream f_in = new FileInputStream(filePath);

                // Read object using ObjectInputStream
                ObjectInputStream obj_in = new ObjectInputStream (f_in);

                // Read an object
                Object obj = obj_in.readObject();
                mdc = (MasterDataContainer) obj;               
            }
            catch(Exception e) {mdc = new MasterDataContainer();}
        }
        else {
            mdc = new MasterDataContainer();
        }
    }
    
    /**
     * Serializes the MasterDataContainer object for persistence.
     * Saves file in location depending on user's operating system.
     */
    private void saveMasterDataContainer() {
        
        String filePath = System.getProperty("user.home");
        String dirPath = System.getProperty("user.home");
        //Determine the operating system.
        if(OperatingSystem.isWindows()) {
            filePath += "\\.JEVEMe\\" + MDC_FILENAME;
            dirPath += "\\.JEVEMe";
        }
        else if(OperatingSystem.isMac()) {
            filePath += "/Library/Application Support/JEVEMe/" + MDC_FILENAME;
            dirPath += "/Library/Application Support/JEVEMe";
        }
        else if(OperatingSystem.isUnix()) {
            filePath += "/.jeveme/" + MDC_FILENAME;
            dirPath += "/.jeveme";
        }
        else {
            filePath += "/.jeveme/" + MDC_FILENAME;
            dirPath += "/.jeveme";
        }
        
        //See if directory exists. if not, create it.
        File dir = new File(dirPath);
        if(!dir.exists()) {
            dir.mkdir();
        }
        
        try {
            // Write to disk with FileOutputStream
            FileOutputStream f_out = new FileOutputStream(filePath);

            // Write object with ObjectOutputStream
            ObjectOutputStream obj_out = new ObjectOutputStream (f_out);

            // Write object out to disk
            obj_out.writeObject ( mdc );
        }
        catch(Exception e){}
        
    }
    
    /**
     * Return the only MasterDataContainer that should be in existence in the whole VM.
     * @return THE MasterDataContainer. It is not a singleton, but should be treated as such.
     */
    public MasterDataContainer getMasterDataContainer() {
        return mdc;
    }
    
    private MasterDataContainer mdc;
    private static final String MDC_FILENAME = "jeveme.data";
    public JEVEMeView jview;
}
